// auth: macro gu
// email & skype: macrogu@hotmail.com

#pragma once

#include <queue>
#include <vector>
#include <sys/epoll.h>
#include <condition_variable>  
#include <mutex>
#include <thread>
#include <functional>

const int STARTED = 0;
const int STOPPED = 1;

class Task
{
    public: 
        Task(std::function<void (void*)> callBackFun, void* arg); // pass a free function pointer
        ~Task();
        void run();
    private:
		std::function<void (void*)> mFTaskRunCB;
        void* m_arg;
};

class ThreadPool
{
    public:
        ThreadPool();
        ~ThreadPool();
        int start();
        int destroy_threadpool();
        void* execute_thread();
        int add_task(Task *task);
        void set_thread_start_cb(std::function<void(void)> startedCB);
        void set_task_size_limit(int size);
        void set_pool_size(int pool_size);
    private:
        int m_pool_size;
		void StartThread(void* arg);		// the thread's call back function
		std::mutex m_task_mutex;
		std::condition_variable_any m_task_cond_var;
		std::vector<std::thread> allThreads;	// storage all threads
        std::queue<Task *> m_tasks;
		std::function<void(void)> mFStartedCB;	//it will be called , when thread start
        volatile int m_pool_state;
        int m_task_size_limit;
};

